package com.android.net

import android.content.Context
import android.util.Log
import com.alibaba.android.arouter.facade.annotation.Route
import com.android.net.api.ApiService
import com.android.net.api.ApiServiceEntryPoint
import com.camera.routemodule.RouterPath
import com.camera.routemodule.routeinterface.NetInterface
import dagger.hilt.android.EntryPointAccessors
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.lang.reflect.Constructor
import kotlin.coroutines.Continuation
import kotlin.jvm.internal.Intrinsics

@Route(path = RouterPath.path.network_api)
class NetworkImpl: NetInterface {
    val TAG = NetworkImpl::class.java.simpleName
    var context : Context? = null
    private val apiService: ApiService by lazy {
        val hiltEntryPoint = EntryPointAccessors.fromApplication(
            context!!.applicationContext,
            ApiServiceEntryPoint::class.java
        )
        hiltEntryPoint.getApiService()
    }
    override fun <T> reqCheckForUpdateApp(clazz: Class<T>, continuation: Continuation<T>) {
        val c = apiService?.checkForUpdate()
        this.sendRequest(c as Call<T>, clazz,continuation)
    }

    private fun <T> sendRequest(request: Call<T>, clazz: Class<T>, continuation: Continuation<T>){
        request.enqueue(object : Callback<T> {
            override fun onResponse(call: Call<T>, response: Response<T>) {
                try {
                    if (response.isSuccessful) {
                        val body = response.body()
                        Log.e(TAG, "onResponse: " +body)
                        if (body != null) {
                            continuation.resumeWith(Result.success(body))
                        } else {
                            val a = createFailResponse(clazz,-1,"statusCode error= Response body is null")
                            continuation.resumeWith(Result.Companion.success(a as T))
                        }
                    } else {
                        val a = createFailResponse(clazz,-1,"statusCode error= ${response.code()}")
                        continuation.resumeWith(Result.Companion.success(a as T))
                    }
                } catch (e: Exception) {
                    val a = createFailResponse(clazz,-1,"statusCode error= ${response.code()}")
                    Log.e(TAG, "onResponse: "+a.toString() )
                    continuation.resumeWith(Result.Companion.success(a as T))
                }
            }

            override fun onFailure(call: Call<T>, t: Throwable) {
                Log.e(TAG, "onFailure: " )
                val a = createFailResponse(clazz,-1,"statusCode error= ${t.message}")
                continuation.resumeWith(Result.Companion.success(a as T))
            }
        })
    }
    override fun init(context: Context?) {
        this.context = context;
    }

    fun createFailResponse(clazz: Class<*>,code: Int = -1,message: String):Any{
        val constructors: Array<Constructor<*>> = clazz.getConstructors()
        Intrinsics.checkNotNullExpressionValue(constructors, "constructors")
        val constructor = constructors.first()
        var any: Any
        val anys: Array<Any?>
        when (constructor.parameterTypes.size) {
            2 -> {
                anys = arrayOf(code, message)
                any = constructor.newInstance(*anys)
            }
            3 -> {
                anys = arrayOf(code, message, null)
                any = constructor.newInstance(*anys)
            }
            else -> any = constructor.newInstance()
        }
        return any
    }
}
